<?php
// +----------------------------------------------------------------------
// | 双擎基础框架 [ 基于ThinkLibrary扩展 ]
// +----------------------------------------------------------------------
// | 感谢ThinkLibrary原作者Anyon的封装
// +----------------------------------------------------------------------
// | Copyright (c) 2022~2024 https://www.sqm.la All rights reserved.
// +----------------------------------------------------------------------
// | Author: rotoos <87291030@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace think\admin\model;

use think\admin\Model;
use think\model\relation\BelongsTo;

/**
 * 系统用户资源关系表模型
 * Class SysRelation
 * @package think\admin\model
 */
class SysRelation extends Model
{
    /**
     * 字段转驼峰
     * @var bool
     */
    protected $convertNameToCamel = true;
    /**
     * 根据分类及对象ID获取目标数据（默认为target_id目标ID）
     * @param string $category
     * @param string $objectIds
     * @param string $field
     * @return array
     */
    public static function getTargetIds(string $category = '', string $objectIds = '', string $field = 'target_id'): array
    {
        return static::mk()->where(['category' => $category])->whereIn('object_id', $objectIds)->column($field);
    }


    /**
     * 根据分类及目标ID获取对象ID
     * @param string $category
     * @param string $targetIds
     * @return array
     */
    public static function getObjectIds(string $category = '', string $targetIds = ''): array
    {
        return static::mk()->where(['category' => $category])->whereIn('target_id', $targetIds)->column('object_id');
    }

    /**
     * 获取一条信息的详情
     * @param $id
     * @return array|mixed|SysRelation|\think\Model
     */
    public static function detail($id)
    {
        return static::mk()->where(['id' => $id])->findOrEmpty();
    }

    /**
     * 关联到Role模型
     * @return BelongsTo
     */
    public function roleHasUser()
    {
        return $this->belongsTo(SysRole::class, 'object_id', 'id')->bind(['roleName'=>'name']);
    }

    /**
     * 关联到Role模型
     * @return BelongsTo
     */
    public function userHasRole()
    {
        return $this->belongsTo(SysRole::class, 'target_id', 'id')->bind(['roleName'=>'name']);
    }

    /**
     * 统一正反向查询公共方法
     * $category1 和 $category2：表示两种不同的关系类别
     * $id：要查询的实体 ID
     * $idField1 和 $idField2：对应于不同关系中的 ID 字段（如 object_id 和 target_id）
     * @param $category1
     * @param $category2
     * @param $id
     * @param $idField1
     * @param $idField2
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getRelations($category1, $category2, $id, $idField1, $idField2): array
    {
        $results = self::mk()
            ->where(function($query) use ($category1, $id, $idField1) {
                $query->where('category', $category1)
                    ->where($idField1, $id);
            })
            ->whereOr(function($query) use ($category2, $id, $idField2) {
                $query->where('category', $category2)
                    ->where($idField2, $id);
            })
            ->field(['target_id', 'object_id', 'ext_json'])
            ->select()
            ->toArray(); // 将结果转换为数组

        // 解析 ext_json 字段为数组并替换 extJson
        return array_map(function($item) {
            if (isset($item['ext_json'])) {
                $decoded = json_decode($item['ext_json'], true);

                // 检查 JSON 解析是否成功
                if (json_last_error() === JSON_ERROR_NONE) {
                    $item['extJson'] = $decoded;
                } else {
                    $item['extJson'] = null; // 或者根据需要设置默认值
                }
            } else {
                $item['extJson'] = null; // 或者根据需要设置默认值
            }

            unset($item['ext_json']); // 移除原来的 ext_json 键

            return $item;
        }, $results);
    }

    /**
     * 通用正反向合并查询方法 取value值
     * // 例子：根据商户ID获取租户ID
     * /*
     * $id = '1337a35f7e5e423d36dd8bd8e1a5eea5';
     * $conditions = [
     * [
     * 'field' => 'object_id',
     * 'category' => 'SYS_MERCHANT_HAS_TENANT',
     * 'returnField' => 'target_id'
     * ],
     * [
     * 'field' => 'target_id',
     * 'category' => 'SYS_TENANT_HAS_MERCHANT',/
     * 'returnField' => 'object_id'
     * ]
     * ];
     * SysRelation::getRelatedId($id,$conditions);$id为商户ID，查询条件如上，返回租户ID
     * /
     * @param $id
     * @param array $conditions
     * @return string|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getRelatedId($id, array $conditions): ?string
    {
        if ($id <= 0) {
            return null;
        }

        $query = self::mk()->where(function($query) use ($id, $conditions) {
            foreach ($conditions as $condition) {
                $query->whereOr(function($subQuery) use ($id, $condition) {
                    $subQuery->where($condition['field'], $id)
                        ->where('category', $condition['category']);
                });
            }
        });

        $caseStatements = [];
        foreach ($conditions as $condition) {
            $caseStatements[] = "WHEN `{$condition['field']}` = '{$id}' AND `category` = '{$condition['category']}' THEN `{$condition['returnField']}`";
        }

        $caseSql = 'CASE ' . implode(' ', $caseStatements) . ' END AS related_id';

        $result = $query->fieldRaw($caseSql)->find();

        return $result ? (string)$result['related_id'] : null;
    }

    /**
     * 通用正反向合并查询方法 取column
     * // 例子：根据商户ID获取租户ID
     * /*
     * $id = '1337a35f7e5e423d36dd8bd8e1a5eea5';
     * $conditions = [
     * [
     * 'field' => 'object_id',
     * 'category' => 'SYS_MERCHANT_HAS_TENANT',
     * 'returnField' => 'target_id'
     * ],
     * [
     * 'field' => 'target_id',
     * 'category' => 'SYS_TENANT_HAS_MERCHANT',/
     * 'returnField' => 'object_id'
     * ]
     * ];
     * @param $id
     * @param array $conditions
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */

    public static function getRelatedColumn($id, array $conditions): array
    {
        if ($id <= 0) {
            return [];
        }

        $query = self::mk()->where(function($query) use ($id, $conditions) {
            foreach ($conditions as $condition) {
                $query->whereOr(function($subQuery) use ($id, $condition) {
                    $subQuery->where($condition['field'], $id)
                        ->where('category', $condition['category']);
                });
            }
        });

        $caseStatements = [];
        foreach ($conditions as $condition) {
            $caseStatements[] = "WHEN `{$condition['field']}` = '{$id}' AND `category` = '{$condition['category']}' THEN `{$condition['returnField']}`";
        }

        $caseSql = 'CASE ' . implode(' ', $caseStatements) . ' END AS related_id';

        $query->fieldRaw($caseSql);

        // 执行查询
        $results = $query->select();

        // 输出结果以查看数据结构
        $resultsArray = $results->toArray();

        // 使用 array_column 提取 related_id 字段的值
        return array_column($resultsArray, 'relatedId');
    }

}